package com.wyh.onlyoffice.controller;


import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.wyh.onlyoffice.dto.Action;
import com.wyh.onlyoffice.dto.Change;
import com.wyh.onlyoffice.dto.History;
import com.wyh.onlyoffice.model.HistoryDoc;
import com.wyh.onlyoffice.model.User;
import com.wyh.onlyoffice.service.HistoryService;
import com.wyh.onlyoffice.service.UserService;
import lombok.extern.slf4j.Slf4j;
import org.apache.tomcat.util.http.fileupload.IOUtils;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLEncoder;
import java.util.List;
import java.util.Map;
import java.util.Scanner;

@Slf4j
@RestController
@RequestMapping("/file")
@CrossOrigin(origins = "*")
public class FileController {

    private final HistoryService historyService;

    public FileController(HistoryService historyService) {
        this.historyService = historyService;
    }

    @GetMapping("/download")
    public void download(@RequestParam("filePath") String filePath,HttpServletResponse response){
        log.info("进入下载文件方法");
        File file = new File(filePath);
        InputStream inputStream = null;
        OutputStream outputStream = null;
        if (file.exists()){
            try {
                String fileName = file.getName();
                inputStream = new FileInputStream(file);
                outputStream = response.getOutputStream();
                response.setHeader("Access-Control-Expose-Headers","Content-Disposition");
                response.setHeader("Content-Disposition", "attachment;filename="
                        + URLEncoder.encode(fileName, "UTF-8"));
                response.setCharacterEncoding("UTF-8");
                response.setContentType("application/vnd.openxmlformats-officedocument.wordprocessingml.document");
                IOUtils.copy(inputStream,outputStream);
            }catch (IOException e){
                log.error("文件读写失败",e);
            }finally {
                IOUtils.closeQuietly(inputStream);
                IOUtils.closeQuietly(outputStream);
            }
        }else{
            log.error("文件不存在");
        }
    }

    @PostMapping("/callback")
    public void callback(@RequestParam("filePath") String filePath, HttpServletRequest request, HttpServletResponse response) {
        log.info("进入回调函数方法,文件路径{}",filePath);
        try {
            PrintWriter writer = response.getWriter();
            String body;
            Scanner scanner = new Scanner(request.getInputStream());
            scanner.useDelimiter("\\A");
            body = scanner.hasNext()?scanner.next():"";
            scanner.close();
            if (body.isEmpty()){
                writer.write("empty request.getInputStream");
                log.error("OfficeController-callback:empty request.getInputStream");
            }
            JSONParser parser = new JSONParser();
            Object obj = parser.parse(body);
            JSONObject jsonObj = (JSONObject) obj;
            long status = (long) jsonObj.get("status");
            if (status == 2 || status == 3){
                String lastSave = (String) jsonObj.get("lastsave");
                log.info("lastSave:{}",lastSave);
                boolean notmodified = (boolean) jsonObj.get("notmodified");
                log.info("notmodified:{}",notmodified);
                String changesurl = jsonObj.get("changesurl").toString();
                log.info("changesurl:{}",changesurl);
                String historyStr = jsonObj.get("history").toString();
                History history = JSON.parseObject(historyStr,History.class);
                log.info("history:{}",history);
                List<Action> actions = (List<Action>) jsonObj.get("actions");
                log.info("actions:{}",actions);
                String key = (String) jsonObj.get("key");
                log.info("key:{}",key);
                String url = (String) jsonObj.get("url");
                log.info("url:{}",url);
                List<String> users = (List<String>) jsonObj.get("users");
                log.info("users:{}",users);
                log.info("下载最新文件");
                URL urlCon = new URL(url);
                URLConnection con = urlCon.openConnection();
                log.info("发生请求下载文件");
                HttpURLConnection connection = (HttpURLConnection) con ;
                long size = connection.getContentLengthLong();
                log.info("获取文件长度:{}",size);
                //获取文件输入流
                InputStream inputStream = connection.getInputStream();
                log.info("获取文件输入流");
                File file = new File(filePath);
                log.info("删除原文件");
                if (!file.delete()) {
                    log.error("删除原文件失败");
                } else {
                    OutputStream outputStream = new FileOutputStream(file);
                    IOUtils.copy(inputStream,outputStream);
                    inputStream.close();
                    outputStream.close();
                    log.info("文件{}保存成功",filePath);
                    // 根据文件路径获取数据库中存在的记录
                    long count = historyService.count(new LambdaQueryWrapper<HistoryDoc>().eq(HistoryDoc::getFilePath, filePath));
                    for (int i = 0; i < history.getChanges().size(); i++) {
                        count++;
                        Change change = history.getChanges().get(i);
                        User user = change.getUser();
                        // 添加历史记录
                        HistoryDoc historyDoc = new HistoryDoc();
                        historyDoc.setVersion(Long.toString(count));
                        historyDoc.setCreated(change.getCreated());
                        historyDoc.setServerVersion(history.getServerVersion());
                        historyDoc.setDocKey(key);
                        historyDoc.setFilePath(filePath);
                        historyDoc.setUrl(url);
                        historyDoc.setUserId(user.getId());
                        if (!historyService.saveOrUpdate(historyDoc)) {
                            log.error("保存{}失败",historyDoc);
                        }else{
                            log.info("保存{}成功",historyDoc);
                        }
                    }
                }
            }
            log.info("当前文档状态:"+status);
            log.info("返回错误状态码:0");
            writer.write("{\"error\":" + 0 + "}");
        }catch (Exception e){
            log.error("class:OfficeController.class,method:callback",e);
        }
    }

    @GetMapping("/create")
    public String create(HttpServletRequest request, HttpServletResponse response){
        log.info("进入创建文件方法");
        return "新建文件";
    }

    @GetMapping("/history/info")
    public String historyInfo(String name,String pwd){
        return "hello world,"+name+":"+pwd;
    }
}
